package com.example.excelzip.util;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.example.excelzip.domain.User;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;

/**
 * @author 陈浩
 * @date 2021/4/14 8:54
 */
public class ExcelZip<T> {

    private ArrayList<File> files;

    private ExcelWriter writer;

    private int pageSize;

    private int begin = 1;

    private T t;

    public ExcelZip(int pageSize) {
        this.pageSize = pageSize;
    }

    public void addExcel(List<T> list, String sheetName) throws Exception {
        checkListAndSetT(list);

        File tempFile = File.createTempFile(getRangeName(list.size()), ".xlsx");

        File excel = writeExcel(tempFile, list, sheetName);

        files.add(excel);
    }

    public void getZipAndOutput(HttpServletResponse response, String fileName) throws IOException {
        int size = this.files.size();

        File[] array = new File[size];
        File[] files = this.files.toArray(array);

        response.setContentType("application/zip");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + "." + "xlsx", "utf-8"));
        ServletOutputStream outputStream = response.getOutputStream();

        ZipUtil.zip(outputStream, CharsetUtil.defaultCharset(), false, (FileFilter)null, files);

        Executors.newSingleThreadExecutor().execute(() -> {
            for (File object : files) {
                object.delete();
            }
        });

    }

    private File writeExcel(File file, List<T> list, String sheetName) {
        writer = EasyExcel.write(file, t.getClass()).build();
        WriteSheet sheet = EasyExcel.writerSheet(sheetName).build();
        writer.write(list, sheet);
        writer.finish();
        return file;
    }

    private String getRangeName(int size) {
        String fileName = null;
        String end = null;

        int b = (begin++ - 1) * pageSize;
        String begin = String.valueOf(b);

        if (size == pageSize) {
            end = String.valueOf(b + pageSize);
        } else {
            end = String.valueOf(b + size);
        }

        fileName = begin + "-" + end + "：";

        return fileName;
    }

    private void checkListAndSetT(List<T> list) throws Exception {
        if (list.isEmpty()) {
            throw new Exception("List is empty!");
        }

        initialization(list);
    }

    private void initialization(List<T> list) {
        if (Objects.isNull(files)) {
            files = new ArrayList<>(10);
        }

        if (t == null) {
            t = list.get(0);
        }
    }

    public void finish() {
        if (files != null) {
            files.clear();
            files = null;
        }

        if (writer != null) {
            writer.finish();
        }

        if (t != null) {
            t = null;
        }

    }

}
